package com.yn.club.auth.domain.service.impl;
import cn.dev33.satoken.secure.SaSecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.Gson;
import com.yn.club.auth.domain.constants.AuthConstant;
import com.yn.club.auth.domain.constants.RedisKey;
import com.yn.club.auth.infra.basic.entity.AuthPermission;
import com.yn.club.auth.infra.basic.entity.AuthRole;
import com.yn.club.auth.infra.basic.entity.AuthRolePermission;
import com.yn.club.auth.infra.basic.entity.AuthUserRole;
import com.yn.club.auth.infra.basic.service.AuthPermissionService;
import com.yn.club.auth.infra.basic.service.AuthRolePermissionService;
import com.yn.club.auth.infra.basic.service.AuthRoleService;
import com.yn.club.auth.infra.basic.service.AuthUserRoleService;
import com.yn.club.common.enums.AuthUserStatusEnum;
import com.yn.club.common.enums.IsDeletedFlagEnum;
import com.yn.club.common.exception.BizException;
import com.yn.club.common.util.PageReq;
import com.yn.club.common.util.PageResp;
import com.yn.club.common.util.RedisUtil;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.yn.club.auth.domain.entity.AuthUserDO;
import com.yn.club.auth.infra.basic.entity.AuthUser;
import com.yn.club.auth.domain.service.AuthUserDomainService;
import com.yn.club.auth.infra.basic.service.AuthUserService;
import com.yn.club.auth.domain.convert.AuthUserDomainConverter;
import org.springframework.transaction.annotation.Transactional;


/**
 * 用户信息表(AuthUser)表服务接口实现类
 *
 * @author YN
 * @since 2025-01-22 10:07:43
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AuthUserDomainServiceImpl implements AuthUserDomainService {

  private final AuthUserService authUserService;
  private final AuthUserDomainConverter authUserDomainConverter;
  private final AuthUserRoleService authUserRoleService;
  private final AuthRoleService authRoleService;
  private final AuthRolePermissionService authRolePermissionService;
  private final AuthPermissionService authPermissionService;
  private final RedisUtil redisUtil;

  /**
   * 分页
   */
  @Override
  public PageResp<AuthUserDO> page(PageReq pageReq, AuthUserDO query){
    QueryWrapper<AuthUser> querywrapper = new QueryWrapper<AuthUser>()
        .eq(query.getId() != null, "id", query.getId())
        .orderByDesc("id");
        
    Page<AuthUser> page = authUserService.page(
      new Page<>(pageReq.getPageIndex(),pageReq.getPageSize()),querywrapper);
    List<AuthUser> list = page.getRecords();  
    return PageResp.of(page,authUserDomainConverter.convertEntityToDo(list));
  }

  /**
   * 新增数据
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public Boolean insert(AuthUserDO authUserDo){
    //1.校验用户是否存在 --根据账号查询
    QueryWrapper<AuthUser> eq = new QueryWrapper<AuthUser>()
        .eq("user_name", authUserDo.getUserName());
    List<AuthUser> list = authUserService.list(eq);
    if (!list.isEmpty()){
      return  true;
    }
    //2.转换为entity
    AuthUser authUser = authUserDomainConverter.convertDoToEntity(authUserDo);
    //3.对密码进行md5加密，当然也选择其他加密方式
    if (StringUtils.isNotBlank(authUser.getPassword())) {
      authUser.setPassword(SaSecureUtil.md5(authUser.getPassword()));
    }
    //3.头像图片，添加默认
    if (StringUtils.isBlank(authUser.getAvatar())) {
      //自己上传图片获取连接
      authUser.setAvatar("https://cos.cdxzwk.cn/umc/image/userLogo/5e6d6e7cceac4695a2ffc1e3121ca498.jpg");
    }
    //4.默认名称
    if (StringUtils.isBlank(authUser.getNickName())) {
      authUser.setNickName("YN社区");
    }

    //5.更新时间字段--可以用mybatis-plus的全局拦截去做新增和修改的 时间字段的自动填充
    authUser.setCreatedTime(LocalDateTime.now());
    authUser.setUpdateTime(LocalDateTime.now());

    //6.状态-默认
    authUser.setStatus(AuthUserStatusEnum.OPEN.getCode());
    authUser.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
    //7.持久化保存
    boolean save = authUserService.save(authUser);


//   用户-角色-权限关联

    // 8.默认绑定normal_user角色，
    AuthRole role = authRoleService.getOne(
        new QueryWrapper<AuthRole>().eq("role_key", AuthConstant.NORMAL_USER));

    //9. 保存中间关系数据进数据库
    Long roleId = role.getId();
    Long userId = authUser.getId();
    AuthUserRole authUserRole = new AuthUserRole();
    authUserRole.setUserId(userId);
    authUserRole.setRoleId(roleId);
    authUserRole.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
    authUserRoleService.save(authUserRole);

    //10.进行redis同步-同步角色
    String roleKey = redisUtil.buildKey(RedisKey.AUTH_ROLE, authUser.getUserName());
    List<AuthRole> roleList = new LinkedList<>();
    roleList.add(role);
    redisUtil.set(roleKey, new Gson().toJson(roleList));
    //11  -同步 角色-权限
    //先查询角色-权限 中间表 把对应关系找出来
    List<AuthRolePermission> rolePermissionList = authRolePermissionService.list(
        new QueryWrapper<AuthRolePermission>().eq("role_id", roleId));
    //获取权限id
    List<Long> permissionIdList = rolePermissionList.stream()
        .map(AuthRolePermission::getPermissionId).collect(Collectors.toList());
    //根据权限ids 获取权限对象
    List<AuthPermission> authPermissionList = authPermissionService.list(new QueryWrapper<AuthPermission>().in("id",permissionIdList));

    // 12 缓存同步 用户-权限对象
    String permissionKey = redisUtil.buildKey(RedisKey.AUTH_PERMISSION, authUser.getUserName());
    redisUtil.set(permissionKey, new Gson().toJson(authPermissionList));
    return save;
  };


  /**
   * 更新数据
   */
  @Override
  public Boolean updateById(AuthUserDO obj){
    AuthUser authUser = authUserDomainConverter.convertDoToEntity(obj);
    authUser.setUpdateTime(LocalDateTime.now());
    return authUserService.updateById(authUser);
  };

  /**
   * 批量删除-伪删除
   */
  @Override
  public Boolean delete(List<Integer> ids){
    UpdateWrapper<AuthUser> set = new UpdateWrapper<AuthUser>()
        .in("id", ids)
        .set("is_deleted", IsDeletedFlagEnum.DELETED.getCode());
    return authUserService.update(set);
  }

  /**
   * 根据id查找
   */
  @Override
  public AuthUserDO getById(Serializable id){
    AuthUser authUser = authUserService.getById(id);
    return  authUserDomainConverter.convertEntityToDo(authUser);
  }

  @Override
  public AuthUserDO getUserInfo(String userName) {
    QueryWrapper<AuthUser> eq = new QueryWrapper<AuthUser>()
        .eq("user_name", userName);
    List<AuthUser> list = authUserService.list(eq);
    if (list.size()==0){
      throw new BizException("无此用户");
    }
    AuthUser authUser = list.get(0);
   if (authUser.getIsDeleted()==IsDeletedFlagEnum.DELETED.getCode()){
     throw new BizException("用户已注销");
   }

    return authUserDomainConverter.convertEntityToDo(authUser);
  }


}

